package com.hyc.netty.server.handler;

import com.hyc.message.RpcRequest;
import com.hyc.message.RpcResponse;
import com.hyc.provider.ServiceProvider;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author 冷环渊
 * @date 2025/6/5 14:03
 * @description NettyRpcServerHandler
 */
@AllArgsConstructor
@Slf4j
public class NettyRpcServerHandler extends ChannelInboundHandlerAdapter {
    private ServiceProvider serviceProvider;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object obj) throws Exception {
        if (obj == null) {
            log.error("没有请求对象");
            return;
        }
        RpcRequest rpcRequest = (RpcRequest) obj;
//        System.out.println("请求的参数为" + rpcRequest);
        boolean token = serviceProvider.getRateLimitProvider().getRateLimitByInterfaceName(rpcRequest.getInterfaceName()).getToken();
        if (token) {
            RpcResponse response = getResponse(rpcRequest);
            ctx.writeAndFlush(response);
        } else {
            RpcResponse fail = RpcResponse.fail(rpcRequest.getRequestId(), "请求被限流");
            System.out.println("服务限流:        " + fail);
            ctx.writeAndFlush(fail);
        }
    }


    private RpcResponse getResponse(RpcRequest rpcRequest) {
        String interfaceName = rpcRequest.getInterfaceName();
        Object service = serviceProvider.getService(interfaceName);
        String methodName = rpcRequest.getMethodName();
        Method method = null;
        try {
            method = service.getClass().getMethod(methodName, rpcRequest.getParamsType());
            //方法结果
            Object invoke = method.invoke(service, rpcRequest.getParams());
            RpcResponse response = RpcResponse.nettySuccess(rpcRequest.getRequestId(), invoke, method.getReturnType());
            System.out.println(response);
            return response;
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            return RpcResponse.fail(rpcRequest.getRequestId(), "调用远程方法出错");
        }
    }
}
